package com.task.common.utils.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import com.task.common.enums.WeekEnum;
import com.task.common.utils.StringUtils;


/**
 * .Date工具类
 */
public final class DateUtil {

  private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class);

  private DateUtil() {
    throw new IllegalStateException("Utility class");
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static String nowDate(String dataFormat) {
    SimpleDateFormat dft = new SimpleDateFormat(dataFormat);
    return dft.format(newDate());
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static Date nowDate() {
    return strToDate(nowDateTimeStr(), DateConstants.DATE_FORMAT_DATE);
  }

  /**
   * .获取当前年,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static String nowYear() {
    Calendar cal = Calendar.getInstance();
    return cal.get(Calendar.YEAR) + "";
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static String nowDateTime(String dataFormat) {
    SimpleDateFormat dft = new SimpleDateFormat(dataFormat);
    return dft.format(newDate());
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static Date nowDateTime() {
    return strToDate(nowDateTimeStr(), DateConstants.DATE_FORMAT);
  }

  /**
   * .获取上一年,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static String lastYear() {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.YEAR, -1);
    return cal.get(Calendar.YEAR) + "";
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static String nowDateTimeStr() {
    return nowDate(DateConstants.DATE_FORMAT);
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static Integer getNowTime() {
    long t = (System.currentTimeMillis() / 1000L);
    return Integer.parseInt(String.valueOf(t));
  }

  /**
   * .获取当前时间戳（秒级） .@return
   */
  public static Long getTime() {
    return (System.currentTimeMillis() / 1000L);
  }

  /**
   * .获取当前日期,指定格式 .描述:描述函数实现的功能. .@return
   */
  public static Date nowDateTimeReturnDate(String dataFormat) {
    SimpleDateFormat dft = new SimpleDateFormat(dataFormat);
    return strToDate(dft.format(newDate()), dataFormat);
  }

  /**
   * .convert a date to string in a specifies fromat.
   */
  public static String dateToStr(Date date, String dataFormat) {
    if (date == null) {
      return null;
    }
    SimpleDateFormat myFormat = new SimpleDateFormat(dataFormat);
    return myFormat.format(date);
  }

  /**
   * .convert a date to string in a specifies fromat.
   */
  public static String dateToStr(Date date) {
    if (date == null) {
      return null;
    }
    SimpleDateFormat myFormat = new SimpleDateFormat(DateConstants.DATE_FORMAT);
    return myFormat.format(date);
  }

  /**
   * .convert a date to string in a specifies fromat.
   */
  public static String strToStr(String dateStr, String startFormat, String endFormat) {
    if (StringUtils.isBlank(dateStr)) {
      return null;
    }
    Date dt = strToDate(dateStr, startFormat);
    return dateToStr(dt, endFormat);
  }

  /**
   * .parse a String to Date in a specifies fromat.
   */
  public static Date strToDate(String dateStr, String dataFormat) {
    SimpleDateFormat myFormat = new SimpleDateFormat(dataFormat);
    try {
      return myFormat.parse(dateStr);
    } catch (ParseException e) {
      return null;
    }
  }

  /**
   * .parse a String to Date in a specifies fromat.
   */
  public static Date strToDate(String dateStr) {
    SimpleDateFormat myFormat = new SimpleDateFormat(DateConstants.DATE_FORMAT);
    try {
      return myFormat.parse(dateStr);
    } catch (ParseException e) {
      return null;
    }
  }

  /**
   * .parse a String to Date in a specifies fromat. lenient 设置为true，为宽松模式
   */
  public static Date strToDate(String dateStr, String dataFormat, Boolean lenient) {
    SimpleDateFormat myFormat = new SimpleDateFormat(dataFormat);
    myFormat.setLenient(lenient);
    try {
      return myFormat.parse(dateStr);
    } catch (ParseException e) {
      return null;
    }
  }

  /**
   * .date add addHour .@param date .@param num .@return
   */
  public static Date addHour(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR_OF_DAY, num);
    return calendar.getTime();
  }

  /**
   * .date add addMinutes .@param date .@param num .@return
   */
  public static Date addMinutes(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MINUTE, num);
    return calendar.getTime();
  }

  /**
   * .date add Second .@param date .@param num .@return
   */
  public static Date addSecond(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.SECOND, num);
    return calendar.getTime();
  }

  /**
   * .date add Second return String
   */
  public static String addSecond(Date date, int num, String dataFormat) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.SECOND, num);
    return dateToStr(calendar.getTime(), dataFormat);
  }

  /**
   * .指定日期加上天数后的日期 .@param num 为增加的天数 .@param newDate 创建时间 .@return
   */
  public static final String addDay(String newDate, int num, String pattern) {
    SimpleDateFormat format = new SimpleDateFormat(pattern);
    try {
      Date currdate = format.parse(newDate);
      Calendar ca = Calendar.getInstance();
      ca.setTime(currdate);
      ca.add(Calendar.DATE, num);
      return format.format(ca.getTime());
    } catch (ParseException e) {
      LOGGER.error("转化时间出错,", e);
      return null;
    }
  }

  /**
   * .指定日期加上天数后的日期 .@param num 为增加的天数 .@param newDate 创建时间 .@return
   */
  public static final String addDay(Date newDate, int num, String pattern) {
    SimpleDateFormat format = new SimpleDateFormat(pattern);
    Calendar ca = Calendar.getInstance();
    ca.setTime(newDate);
    ca.add(Calendar.DATE, num);
    return format.format(ca.getTime());
  }

  /**
   * .date add addMonth .@param date .@param num .@return
   */
  public static Date addDay(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.DATE, num);
    return calendar.getTime();
  }

  /**
   * .date add addMonth .@param date .@param num .@return
   */
  public static Date addMonth(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, num);
    return calendar.getTime();
  }

  /**
   * .date add addYear .@param date .@param num .@return
   */
  public static Date addYear(Date date, int num) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.YEAR, num);
    return calendar.getTime();
  }

  /**
   * 计算某一天是一个月的哪一天.
   */
  public static int day(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return day(cal);
  }

  public static int day(Calendar calendar) {
    return calendar.get(Calendar.DAY_OF_MONTH);
  }

  /**
   * 计算某一天是星期几.
   */
  public static int week(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return week(cal);
  }

  public static int week(Calendar calendar) {
    return calendar.get(Calendar.DAY_OF_WEEK) - 1;
  }

  /**
   * 计算某一天是星期几.
   */
  public static String weekName(Date date, String pre) {
    int weekval = week(date);
    String weekname = "";
    switch (weekval) {
      case 1:
        weekname = "一";
        break;
      case 2:
        weekname = "二";
        break;
      case 3:
        weekname = "三";
        break;
      case 4:
        weekname = "四";
        break;
      case 5:
        weekname = "五";
        break;
      case 6:
        weekname = "六";
        break;
      case 0:
        weekname = "日";
        break;
      default:
        break;
    }
    if (StringUtils.isBlank(weekname)) {
      return "";
    }
    return pre + weekname;
  }


  /**
   * 计算某一天的月份.
   *
   * @param date 日期
   * @return 月份, 1开始
   */
  public static int month(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return month(cal);
  }

  public static int month(Calendar calendar) {
    return calendar.get(Calendar.MONTH) + 1;
  }

  /**
   * 计算某一天的年.
   */
  public static int year(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return year(cal);
  }

  public static int year(Calendar calendar) {
    return calendar.get(Calendar.YEAR);
  }

  /**
   * 计算某一天的时.
   *
   * @param date 日期
   * @return 时 0-23
   */
  public static int hour(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return hour(cal);
  }

  public static int hour(Calendar calendar) {
    return calendar.get(Calendar.HOUR_OF_DAY);
  }

  /**
   * 计算某一天的分.
   *
   * @param date 日期
   * @return 秒 0-59
   */
  public static int minute(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return minute(cal);
  }

  public static int minute(Calendar calendar) {
    return calendar.get(Calendar.MINUTE);
  }

  /**
   * 计算某一天的秒.
   *
   * @param date 日期
   * @return 秒 0-59
   */
  public static int second(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return second(cal);
  }

  public static int second(Calendar calendar) {
    return calendar.get(Calendar.SECOND);
  }

  /**
   * 计算两个时分秒时间的差距是否在给定的容忍范围内.
   *
   * @param one     比较的一方
   * @param two     比较的另外一方
   * @param seconds 容忍范围
   * @return true if in the range of seconds or false if out of the range
   */
  public static boolean equalsWithTolerance(TimeOfDay one, TimeOfDay two, Integer seconds) {
    // 秒数为0退化为equals
    if (null == seconds || 0 == seconds) {
      return one.equals(two);
    }
    // 秒数是否在给定的容忍范围内
    return distance(one, two) <= seconds;
  }

  public static long distance(TimeOfDay one, TimeOfDay two) {
    Calendar calendar1 = Calendar.getInstance();
    calendar1.set(Calendar.HOUR_OF_DAY, one.getHour());
    calendar1.set(Calendar.MINUTE, one.getMinute());
    calendar1.set(Calendar.SECOND, one.getSecond());

    Calendar calendar2 = Calendar.getInstance();
    calendar2.set(Calendar.HOUR_OF_DAY, two.getHour());
    calendar2.set(Calendar.MINUTE, two.getMinute());
    calendar2.set(Calendar.SECOND, two.getSecond());

    // 秒数是否在给定的容忍范围内
    return Math.abs(calendar1.getTimeInMillis() / 1000 - calendar2.getTimeInMillis() / 1000);
  }

  /**
   * 本月第一天 00:00:00.
   */
  public static Date monthfirstday(Date date) {
    String firststr = dateToStr(date, "yyyy-MM-01 00:00:00");
    return strToDate(firststr);
  }

  /**
   * 本月第一天 00:00:00.
   */
  public static Date monthfirstday(String date) {
    Date d = strToDate(date);
    String firststr = dateToStr(d, "yyyy-MM-01 00:00:00");
    return strToDate(firststr);
  }

  /**
   * 本月最后一天 23:59:59.
   */
  public static Date monthlastday(Date date) {
    return addSecond(addMonth(monthfirstday(date), 1), -1);
  }

  /**
   * 本月最后一天 23:59:59.
   */
  public static Date monthlastday(String date) {
    return addSecond(addMonth(monthfirstday(date), 1), -1);
  }

  /**
   * .convert long to date .@param date 待转换时间戳 .@return 转换后时间
   */
  public static Date timeStamp11ToDate(long date) {
    return new Date(date);
  }

  /**
   * .convert long to date string
   */
  public static String timeStamp11ToDate(long date, String dataFormat) {
    return dateToStr(new Date(date), dataFormat);
  }

  /**
   * .compare two date String with a pattern
   */
  public static int compareDate(String date1, String date2, String pattern) {
    SimpleDateFormat dataFormat = new SimpleDateFormat(pattern);
    try {
      Date dt1 = dataFormat.parse(date1);
      Date dt2 = dataFormat.parse(date2);
      if (dt1.getTime() > dt2.getTime()) {
        return 1;
      } else if (dt1.getTime() < dt2.getTime()) {
        return -1;
      } else {
        return 0;
      }

    } catch (ParseException e) {
      e.printStackTrace();
      return 0;
    }
  }

  /**
   * .检查日期格式是否合法 .@param date .@param style .@return
   */
  public static boolean checkDateFormat(String date, String style) {
    SimpleDateFormat dataFormat = new SimpleDateFormat(style);
    try {
      // 设置lenient为false.
      // 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
      dataFormat.setLenient(false);
      dataFormat.parse(date);
      return true;
    } catch (ParseException e) {
      return false;
    }
  }

  /**
   * .计算两个时间之间的天数差 .@param beforeDay 开始时间 .@param afterDay 结束时间 .@return 相差天数
   */
  public static long getTwoDateDays(Date beforeDay, Date afterDay) {
    SimpleDateFormat sm = new SimpleDateFormat(DateConstants.DATE_FORMAT_NUM);
    long days = -1;
    try {
      days =
          (sm.parse(sm.format(afterDay)).getTime() - sm.parse(sm.format(beforeDay)).getTime())
              / (1000 * 3600 * 24);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return days;
  }

  /**
   * .计算两个时间之间的小时差 .@param beforeDay 开始时间 .@param afterDay 结束时间 .@return 相差天数
   */
  public static long getTwoDateHour(Date beforeDay, Date afterDay) {
    SimpleDateFormat sm = new SimpleDateFormat(DateConstants.DATE_FORMAT);
    long days = -1;
    try {
      days =
          (sm.parse(sm.format(afterDay)).getTime() - sm.parse(sm.format(beforeDay)).getTime())
              / (1000 * 60 * 60);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return days;
  }

  // 获取时间戳11位
  public static int getSecondTimestamp(Date date) {
    if (null == date) {
      return 0;
    }
    String timestamp = String.valueOf(date.getTime() / 1000);
    return Integer.parseInt(timestamp);
  }

  // 获取时间戳11位
  public static int getSecondTimestamp(String date) {
    if (null == date) {
      return 0;
    }
    Date date1 = strToDate(date, DateConstants.DATE_FORMAT);
    if (date1 == null) {
      return 0;
    }
    String timestamp = String.valueOf(date1.getTime() / 1000);
    return Integer.parseInt(timestamp);
  }

  // 获取时间戳10位
  public static int getSecondTimestamp(Long timeMillis) {
    if (null == timeMillis) {
      return 0;
    }
    String timestamp = String.valueOf(timeMillis / 1000);
    return Integer.parseInt(timestamp);
  }

  // 获取时间戳11位
  public static int getSecondTimestamp() {
    Date date = strToDate(nowDateTime(DateConstants.DATE_FORMAT), DateConstants.DATE_FORMAT);
    if (null == date) {
      return 0;
    }
    String timestamp = String.valueOf(date.getTime() / 1000);
    return Integer.parseInt(timestamp);
  }

  /**
   * .获得昨天日期:yyyy-MM-dd HH:mm:ss
   */
  public static String getYesterdayStr() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.DATE, -1);
    SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return startSdf.format(c.getTime());
  }

  /**
   * .获得本周第一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getWeekStartDay() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.WEEK_OF_MONTH, 0);
    c.set(Calendar.DAY_OF_WEEK, 2);
    SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
    return startSdf.format(c.getTime());
  }

  /**
   * .获得本周第一天:yyyy-MM-dd HH:mm:ss
   */
  public static Date getWeekStartDayDt() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.WEEK_OF_MONTH, 0);
    c.set(Calendar.DAY_OF_WEEK, 2);
    return c.getTime();
  }

  /**
   * .获得本周最后一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getWeekEndDay() {
    return addDay(getWeekStartDay(), 7, DateConstants.DATE_FORMAT);
  }

  /**
   * .获得上周第一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastWeekStartDay() {
    return addDay(getWeekStartDay(), -7, DateConstants.DATE_FORMAT);
  }

  /**
   * .获得上周最后一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastWeekEndDay() {
    return addDay(getLastWeekStartDay(), 7, DateConstants.DATE_FORMAT);
  }

  /**
   * .获得本月最后一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getMonthEndDay() {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
    SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
    return endSdf.format(c.getTime());
  }

  /**
   * .获得本月最后一天
   */
  public static String getMonthEndDay(String format) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
    SimpleDateFormat endSdf = new SimpleDateFormat(format);
    return endSdf.format(c.getTime());
  }

  /**
   * .获得上月第一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastMonthStartDay() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.MONTH, -1);
    c.set(Calendar.DAY_OF_MONTH, 1);
    SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-01 00:00:00");
    return startSdf.format(c.getTime());
  }

  /**
   * .获得上月最后一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastMonthEndDay() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.MONTH, -1);
    c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
    SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
    return endSdf.format(c.getTime());
  }

  /**
   * .获得上年第一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastYearStartDay() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.YEAR, -1);
    SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
    return startSdf.format(c.getTime());
  }

  /**
   * .获得上年最后一天:yyyy-MM-dd HH:mm:ss
   */
  public static String getLastYearEndDay() {
    Calendar c = Calendar.getInstance();
    c.add(Calendar.YEAR, -1);
    SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
    return endSdf.format(c.getTime());
  }

  /**
   * .两个日期之前的相差小时数 .@param starDate 开始日期 .@param endDate 结束日期 .@return 相差天数
   */
  public static int hoursBetween(Date starDate, Date endDate) {

    Calendar cal = Calendar.getInstance();

    cal.setTime(starDate);

    long time1 = cal.getTimeInMillis();

    cal.setTime(endDate);

    long time2 = cal.getTimeInMillis();

    long betweenHours = (time2 - time1) / (1000 * 3600);

    return Integer.parseInt(String.valueOf(betweenHours));
  }

  /**
   * .两个日期之前的相差天数 .@param starDate 开始日期 .@param endDate 结束日期 .@return 相差天数
   */
  public static int daysBetween(Date starDate, Date endDate) {

    Calendar cal = Calendar.getInstance();

    cal.setTime(starDate);

    long time1 = cal.getTimeInMillis();

    cal.setTime(endDate);

    long time2 = cal.getTimeInMillis();

    long betweenDays = (time2 - time1) / (1000 * 3600 * 24);

    return Integer.parseInt(String.valueOf(betweenDays));
  }

  /**
   * .获取指定日期指定格式字符串
   */
  public static String appointedDayStrToFormatStr(
      String dateStr, String strDataFormat, String dataFormat) {
    Date date = DateUtil.strToDate(dateStr, strDataFormat);
    return DateUtil.dateToStr(date, dataFormat);
  }

  /**
   * .获取当前时间小时 .@return 当前时间小时 默认24小时
   */
  public static int getCurrentHour() {
    int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    return hour;
  }

  /**
   * .13位时间戳转字符串
   */
  public static String timestamp2DateStr(Long timestamp, String dateFormat) {
    if (ObjectUtil.isNull(timestamp)) {
      return "";
    }
    if (StrUtil.isBlank(dateFormat)) {
      dateFormat = DateConstants.DATE_FORMAT;
    }
    Date date = new Date(timestamp);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
    return simpleDateFormat.format(date);
  }

  /**
   * .字符串转13位时间戳
   */
  public static Long dateStr2Timestamp(String dateStr, String type) {
    DateTime parse = cn.hutool.core.date.DateUtil.parse(dateStr);
    if (StrUtil.isNotBlank(type)) {
      if (type.equals(DateConstants.DATE_TIME_TYPE_BEGIN)) {
        parse = cn.hutool.core.date.DateUtil.beginOfDay(parse);
      }
      if (type.equals(DateConstants.DATE_TIME_TYPE_END)) {
        parse = cn.hutool.core.date.DateUtil.endOfDay(parse);
      }
    }
    return parse.getTime();
  }

  /**
   * 获取格式化时间串.
   */
  public static Date fmdate(Date now, String ft) {
    if (StringUtils.isBlank(ft)) {
      return now;
    }
    // y年 m月 d日 h时 f分 s秒
    Date newDt = now;
    if (ft.startsWith("d")
        || ft.startsWith("y")
        || ft.startsWith("m")
        || ft.startsWith("h")
        || ft.startsWith("w")) {
      ft = ft.replace(" ", "");
      String tmpTmstr = ft.substring(1);
      String prex = tmpTmstr.substring(0, 1);
      String numStr = tmpTmstr.substring(1);
      Integer num = StringUtils.isNotBlank(numStr) ? Integer.parseInt(numStr) : 0;
      if (prex != null && prex.equals("-")) {
        num = num * -1;
      }
      if (ft.startsWith("d")) { // 日
        newDt = DateUtil.addDay(now, num);
      } else if (ft.startsWith("y")) { // 年
        newDt = DateUtil.addYear(now, num);
      } else if (ft.startsWith("m")) { // 月
        newDt = DateUtil.addMonth(now, num);
      } else if (ft.startsWith("h")) { // h时
        newDt = DateUtil.addHour(now, num);
      } else if (ft.startsWith("w")) { // 星期（+日期，从本周第一天算）
        Date wstart = getWeekStartDayDt();
        newDt = DateUtil.addDay(wstart, num);
      }
      return newDt;
    } else {
      return DateUtil.strToDate(ft, DateConstants.DATE_FORMAT);
    }
  }

  /**
   * 获取格式化时间串.
   */
  public static String fmtimes(Date now, String tmpFormat) {
    if (StringUtils.isBlank(tmpFormat)) {
      return DateUtil.dateToStr(now, DateConstants.DATE_FORMAT);
    }
    // d+1,yyyy-MM-dd 08:00:00
    String[] dvalue = tmpFormat.split(",");
    if (dvalue.length > 0) {
      String ft = dvalue[0];
      String dayStr = "";
      Date newDt = fmdate(now, ft);
      // y年 m月 d日 h时 f分 s秒
      if (dvalue.length > 1 && StringUtils.isNotBlank(dvalue[1])) {
        dayStr = DateUtil.dateToStr(newDt, dvalue[1].trim());
      } else {
        dayStr = DateUtil.dateToStr(newDt, DateConstants.DATE_FORMAT);
      }
      return dayStr;
    }
    return DateUtil.dateToStr(now, DateConstants.DATE_FORMAT);
  }

  /**
   * 获取格式化时间串.
   */
  public static String strToFmStr(String times, String endfm) {
    if (StringUtils.isBlank(times) || StringUtils.isBlank(endfm)) {
      return "";
    }
    if (endfm.contains(",")) {
      Date endtm = DateUtil.strToDate(times, DateConstants.DATE_FORMAT);
      return DateUtil.fmtimes(endtm, endfm);
    } else {
      return DateUtil.strToStr(times, DateConstants.DATE_FORMAT, endfm);
    }
  }

  /*
   *  时间小时就近取整
   */
  public static Date getCompleteTimeByTimeAuto(Date time) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);
    int minute = cal.get(Calendar.MINUTE);
    if (minute >= 30) {
      //如果当前分钟大于30,就向上取整时
      cal.add(Calendar.HOUR, 1);
    }
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    return cal.getTime();
  }

  /**
   *  时间小时就近取整.
   */
  public static Date getCompleteTimeByTimeAuto() {
    return getCompleteTimeByTimeAuto(newDate());
  }

  /**
   *  时间小时向下取整.
   */
  public static Date getCompleteTimeByTimeDown(Date time) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);
    //int minute = cal.get(Calendar.MINUTE);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    return cal.getTime();
  }

  /**
   *  时间小时向下取整.
   */
  public static Date getCompleteTimeByTimeDown() {
    return getCompleteTimeByTimeDown(newDate());
  }

  /**
   *  时间分钟获取整数十位 向下取整.
   */
  public static Date getCompleteTimeMinByTimeDown(Date time) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);
    int minute = cal.get(Calendar.MINUTE);
    if (minute < 10) {
      cal.set(Calendar.MINUTE, 0);
    } else if (minute < 20) {
      cal.set(Calendar.MINUTE, 10);
    } else if (minute < 30) {
      cal.set(Calendar.MINUTE, 20);
    } else if (minute < 40) {
      cal.set(Calendar.MINUTE, 30);
    } else if (minute < 50) {
      cal.set(Calendar.MINUTE, 40);
    } else {
      cal.set(Calendar.MINUTE, 50);
    }
    cal.set(Calendar.SECOND, 0);
    return cal.getTime();
  }

  /*
   *  时间小时向上取整
   */
  public static Date getCompleteTimeByTimeUp(Date time) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(time);
    //int minute = cal.get(Calendar.MINUTE);
    cal.add(Calendar.HOUR, 1);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    return cal.getTime();
  }

  /*
   *  根据时间获取当天凌晨时间
   */
  public static Date getDayStart(Date time) {
    return strToDate(dateToStr(time, DateConstants.DATE_FORMAT_START));
  }

  /*
   *  获取凌晨时间
   */
  public static Date getDayStart() {
    return getDayStart(newDate());
  }

  /*
   *  根据时间获取当天最后一秒时间
   */
  public static Date getDayEnd(Date time) {
    return strToDate(dateToStr(time, DateConstants.DATE_FORMAT_END));
  }

  /*
   *  获取凌晨时间
   */
  public static Date getDayEnd() {
    return getDayEnd(newDate());
  }

  //获取当前周几数字
  public static WeekEnum getWeek() {
    // 创建Calendar对象
    LocalDate today = LocalDate.now();  // 获取当前日期
    DayOfWeek dayOfWeek = today.getDayOfWeek();  // 获取星期几
    int dayValue = dayOfWeek.getValue();  // 获取数字值（1=Monday, 7=Sunday）
//    Calendar calendar = Calendar.getInstance();
    return WeekEnum.getEnumByInfo(dayValue);
  }

  /**
   * 两个时间差计算.
   */
  public String getDatePoor(Date endDate, Date nowDate) {
    long nd = 1000 * 24 * 60 * 60;
    long nh = 1000 * 60 * 60;
    long nm = 1000 * 60;
    long ns = 1000;
    // 获得两个时间的毫秒时间差异
    long diff = endDate.getTime() - nowDate.getTime();
    // 计算差多少天
    long day = diff / nd;
    // 计算差多少小时
    long hour = diff % nd / nh;
    // 计算差多少分钟
    long min = diff % nd % nh / nm;
    // 计算差多少秒//输出结果
    long sec = diff % nd % nh % nm / ns;
    return day + "天" + hour + "小时" + min + "分钟" + sec + "秒";
  }

  public static Date newDate() {
    //if(FunctionUtil.isLinux()) {
    //  return new Date();
    //}
    Calendar cd = Calendar.getInstance(Locale.CHINA);
    return cd.getTime();
  }

  public static String newDateStr() {
    return dateToStr(newDate(), DateConstants.DATE_FORMAT);
  }

  public static boolean timeEqByType(Date time1, Date time2, String type) {
    return dateToStr(time1, type).equals(dateToStr(time2, type));
  }

  public static boolean isSameDay(Date time1, Date time2) {
    return timeEqByType(time1, time2, "dd");
  }

  public static boolean isSameMonth(Date time1, Date time2) {
    return timeEqByType(time1, time2, "MM");
  }

  public static boolean isSameYear(Date time1, Date time2) {
    return timeEqByType(time1, time2, "yyyy");
  }

  /**
   * 判断是否是白天 08-20白天  其他时间夜晚.
   * @param date 时间
   * @return true
   */
  public static Boolean isDay(Date date) {
    Date time = newDate();
    Date dayStartTime = strToDate((dateToStr(time, DateConstants.DATE_FORMAT_DATE) + " 08:00:00"),
        DateConstants.DATE_FORMAT);
    Date dayEndTime = strToDate((dateToStr(time, DateConstants.DATE_FORMAT_DATE) + " 20:00:00"),
        DateConstants.DATE_FORMAT);
    if ((date.after(dayStartTime) || date.equals(dayStartTime)) && date.before(dayEndTime)) {
      return true;
    }
    return false;
  }


  /**
   * 判断是否是夜晚 08-20白天  其他时间夜晚.
   * @param date 时间
   * @return true
   */
  public static Boolean isNight(Date date) {
    return !isDay(date);
  }

  /**
   * 获取指定日期的月份（1-12）。
   * @param date 日期
   * @return 月份（1-12）
   */
  public static int getMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.MONTH) + 1;  // Calendar.MONTH返回的月份是0到11，因此需要加1
  }

  /**
   * 获取指定日期的年份。
   * @param date 日期
   * @return 年份（例如2025）
   */
  public static int getYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.YEAR);  // 获取年份
  }
}
